package com.fla.shapeevader.ui;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.SurfaceHolder.Callback;

import com.fla.shapeevader.ui.drawers.BaseShapeDrawer;
import com.fla.shapeevader.ui.drawers.UserShapeDrawer;

public class GameView extends SurfaceView implements Callback {

    public interface GameEventListener {
        void onIntersectionOccured();
    }

    private GameStateDrawerThread stateDrawer;

    private boolean surfaceCreated = false;
    private boolean gameShouldStart = false;

    private GameEventListener gameEventListener;

    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);

        getHolder().addCallback(this);
    }

    public void setGameEventListener(GameEventListener listener) {
        gameEventListener = listener;
    }

    public void initAndStart(UserShapeDrawer userShape, BaseShapeDrawer... shapes) {
        if (stateDrawer != null) {
            stopGame();
        }
        stateDrawer = new GameStateDrawerThread(getHolder(), getContext(), new GameHandler());

        stateDrawer.setUserShape(userShape);

        for (BaseShapeDrawer baseShapeDrawer : shapes) {
            stateDrawer.addShape(baseShapeDrawer);
        }
        stateDrawer.setSurfaceSize(getWidth(), getHeight());

        if (surfaceCreated) {
            startGame();
        } else {
            gameShouldStart = true;
        }

        setOnTouchListener(new TouchListener());
    }

    private void startGame() {
        stateDrawer.setRunning(true);
        stateDrawer.start();

        gameShouldStart = false;
        Log.d("test", "game started");
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        stateDrawer.setSurfaceSize(width, height);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.d("test", "surfaceCreated");
        surfaceCreated = true;

        if (gameShouldStart) {
            startGame();
        }
    }

    private void stopGame() {
        // we have to tell thread to shut down & wait for it to finish, or else
        // it might touch the Surface after we return and explode
        boolean retry = true;
        stateDrawer.setRunning(false);
        while (retry) {
            try {
                stateDrawer.join();
                retry = false;
            } catch (InterruptedException e) {
                Log.e("test", "InterruptedException", e);
            }
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        stopGame();
    }

    private class TouchListener implements OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            stateDrawer.dispatchTouchEvent(event);
            return true;
        }
    }

    private class GameHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            Log.d("test", "Message handled: " + msg);
            boolean intersection = msg.getData().getBoolean(GameStateDrawerThread.INTERSECTION_OCCURED_KEY, false);
            if (intersection && gameEventListener != null) {
                gameEventListener.onIntersectionOccured();
            }
        }
    }
}
